﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using Sina.Altman.Weibo.Tools;
using System.IO;
using System.Text;
using Sina.Altman.Weibo.SDK.Objects;

namespace Sina.Altman.Weibo.SDK
{
    public class LocationRequest
    {

        static string token = Enviroment.Token;
        /// <summary>
        /// 获取公共信息流，返回值可能为null注意检查
        /// 获取操作为异步操作
        /// </summary>
        /// <param name="parameters">可加参数</param>
        /// <returns></returns>
        public static void GetRequest(LocationType type, LocationRequestData data, Action<object> callback)
        {
            var request = (HttpWebRequest)WebRequest.Create(new Uri(GetRequestUri(type, data), UriKind.Absolute));

            request.Method = "GET";
            var inner = request.BeginGetResponse(ResponseCallback, new LocationUserState() { Callback = callback, Request = request, RequestData = data, Type = type });


        }

        /// <summary>
        /// 计算Post数据的长度
        /// </summary>
        /// <param name="result"></param>
        /// <param name="data"></param>
        /// <param name="type"></param>
        /// <param name="callback"></param>
        private static void RequestStreamCallback(IAsyncResult asyncResult)
        {
            FriendShipUserState state = (FriendShipUserState)asyncResult.AsyncState;
            HttpWebRequest request = state.Request;
            Stream body = request.EndGetRequestStream(asyncResult);

            //if (type == StateType.Upload)
            //{
            //    PrepareFileData(state, request, body);
            //}
            //else if (type == StateType.Repost)
            //{
            //    string postData = string.Empty;
            //    postData = "access_token=" + token + "&id=" + state.RequestData.WeiboID + Uri.EscapeDataString(state.RequestData.WeiboContent.Status);

            //    byte[] bytes = Encoding.UTF8.GetBytes(postData);
            //    body.Write(bytes, 0, bytes.Length);
            //    body.Flush();
            //    body.Close();
            //}
            //else if (type == StateType.Delete)
            //{
            //    string postData = string.Empty;
            //    postData = "access_token=" + token + "&id=" + state.RequestData.WeiboID;

            //    byte[] bytes = Encoding.UTF8.GetBytes(postData);
            //    body.Write(bytes, 0, bytes.Length);
            //    body.Flush();
            //    body.Close();
            //}
            string postData = string.Empty;
            postData = "access_token=" + token + "&uid=" + state.RequestData.UserID;

            byte[] bytes = Encoding.UTF8.GetBytes(postData);

            body.Write(bytes, 0, bytes.Length);

            body.Flush();

            body.Close();


            request.BeginGetResponse((result) => ResponseCallback(result), state);
        }

        /// <summary>
        /// 准备上传的流
        /// </summary>
        /// <param name="state">包含上传的数据</param>
        /// <param name="request">发送请求</param>
        /// <param name="body">流</param>
        private static void PrepareFileData(StatusesUserState state, HttpWebRequest request, Stream body)
        {
            //var boundary = string.Concat("--", Util.GenerateRndNonce());
            //byte[] beginBoundary = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
            //byte[] endBoundary = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");

            //string paraTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
            //string fileTemplate = "Content-Disposition: form-data; name=\"{0}\";filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";

            //Files files = state.RequestData.WeiboContent.Files;

            //request.ContentType = string.Concat("multipart/form-data; boundary=", boundary);

            //using (MemoryStream memStream = new MemoryStream())
            //{
            //    foreach (var item in state.RequestData.WeiboContent.Parameters)
            //    {
            //        string value = item.Value;
            //        byte[] bpara = Encoding.UTF8.GetBytes(string.Format(paraTemplate, item.Name, value));
            //        memStream.Write(beginBoundary, 0, beginBoundary.Length);
            //        memStream.Write(bpara, 0, bpara.Length);
            //    }

            //    foreach (var file in files.Items)
            //    {
            //        byte[] bfile = Encoding.UTF8.GetBytes(string.Format(fileTemplate, file.Key, file.Value.FileName, file.Value.ContentType));
            //        memStream.Write(beginBoundary, 0, beginBoundary.Length);
            //        memStream.Write(bfile, 0, bfile.Length);

            //        file.Value.WriteTo(memStream);

            //        memStream.Write(endBoundary, 0, endBoundary.Length);
            //    }

            //    memStream.WriteTo(body);
            //    body.Flush();
            //    body.Close();
            //}
        }

        /// <summary>
        /// 回调 
        /// </summary>
        /// <param name="result"></param>
        private static void ResponseCallback(IAsyncResult result)
        {
            var userState = result.AsyncState as LocationUserState;

            try
            {
                var request = userState.Request as HttpWebRequest;
                var respone = (HttpWebResponse)request.EndGetResponse(result);

                var stream = respone.GetResponseStream();
                using (StreamReader reader = new StreamReader(stream))
                {
                    string jsonRes = reader.ReadToEnd();
                    
                    if (!string.IsNullOrEmpty(jsonRes))
                    {
                        if (userState.Type == LocationType.GroToAddress)
                        {
                            Geos status = new Geos(jsonRes);
                            if (null != userState.Callback)
                            {
                                userState.Callback(status);
                            }
                        }
                        else if(userState.Type==LocationType.LocationToPois)
                        {
                            Pois status = new Pois(jsonRes);
                            if (null != userState.Callback)
                            {
                                userState.Callback(status);
                            }
                        }


                    }
                }
            }
            catch (Exception e)
            {
                if (null != userState.Callback)
                    userState.Callback(e);
            }
        }

        /// <summary>
        /// 获取请求地址
        /// </summary>
        /// <param name="queryType"></param>
        /// <returns></returns>
        private static string GetRequestUri(LocationType queryType, LocationRequestData data)
        {
            if (string.IsNullOrEmpty(token))
                token = ISHelper.LoadSetting<string>(Constants.User_Access_Token_SR, string.Empty);
            string fullUri = string.Empty;

            switch (queryType)
            {
                case LocationType.GroToAddress:
                    fullUri = Constants.GEO_TO_ADDRESS + "?access_token=" + token + "&coordinate="+data.Longitude+","+data.Latitude;
                    break;
                case LocationType.LocationToPois:
                    fullUri = Constants.LOCATION_TO_POIS + "?access_token=" + token + "&q=" + data.QueryKey;
                    break;
                default:
                    break;
            }

            return fullUri;
        }
    }

    public class LocationUserState : UserState
    {
        public LocationRequestData RequestData { get; set; }

        public LocationType Type { get; set; }
    }

    public enum LocationType
    {
        GroToAddress,
        LocationToPois,
    }

    public class LocationRequestData : RequestData
    {
        public string Longitude { get; set; }
        public string Latitude { get; set; }
        public string QueryKey { get; set; }
    }
}
